class AxiosError {
	constructor(info={}) {
		this.code = info.code;//"ERR_BAD_REQUEST";
		this.config = info.config;
		this.message = info.message;// "Request failed with status code "+status;
		this.name = info.name;
		if(info.response)
			this.response = info.response;
		if(info.request)
			this.request = info.request;
	}
}
const defaults = {
	timeout:1000
}
class Axios {
	constructor(instanceConfig) {
		// this.defaults的值为全局默认项。
		this.defaults = instanceConfig;
		
	}
	request(configOrUrl, config = {}) {
		if (typeof configOrUrl === "string") config.url = configOrUrl;
		else config = configOrUrl;
		config = {
			...this.defaults,
			...config
		}
		console.log(config);
		config.method = (config.method || "get").toLowerCase();
		const dispatchRequest = function () {
			return new Promise(function (resolve, reject) {
				if (config.params) {
					config.url += "?" + Object.keys(config.params).map(key => key + "=" + config.params[key]).join("&");
				}
				
				if(config.baseURL && !config.url.startsWith("http://")){
					config.url = config.baseURL+config.url;
				}
				
				
				const request = new XMLHttpRequest();
				if(config.timeout) request.timeout = config.timeout;
				request.responseType = "json";
				request.open(config.method, config.url);
				if(config.headers){
					for(let key in config.headers){
						console.log(key,config.headers[key])
						request.setRequestHeader(key,config.headers[key]);
					}
				}
				
				if(config.method === "post" && config.data){
					if(typeof config.data === "object"){
						request.setRequestHeader("Content-Type","application/json");
						config.data = JSON.stringify(config.data);
					}else request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
				}
				request.send(config.data);
				
				
				
				
				// 当得到响应信息后执行（请求的资源如果有响应即执行）
				request.onload = function () {
					if(request.status === 200){
						
						resolve({
							// 配置对象信息
							config,
							// 响应头
							headers: request.getAllResponseHeaders(),
							// 响应体
							data: request.response,
							// XMLHttpRequest实例
							request,
							// 状态码
							status: request.status,
							// 状态码说明
							statusText: request.statusText
						})
					}else{
						//404
						reject(new AxiosError({
							code:"ERR_BAD_REQUEST",
							config,
							message:"Request failed with status code "+request.status,
							name:"AxiosError",
							response:request.response
						}))
					}
				}
				request.onerror = function(){
					reject(new AxiosError({
						code:"ERR_NETWORK",
						config,
						message:"Network Error",
						name:"AxiosError",
						request
					}))
				}
				request.ontimeout = function(){
					reject(new AxiosError({
						code:"ECONNABORTED",
						name:"AxiosError",
						config,
						request,
						message:`timeout of ${request.timeout}ms exceeded`					}))
				}
			})
		}
		return dispatchRequest();
	}
}

function createInstance(defaultConfig) {
	const context = new Axios(defaultConfig);
	const instance = Axios.prototype.request.bind(context);
	for(let key in context){
		instance[key] = context[key];
	}
	
	return instance;
}

const axios = createInstance(defaults);
export default axios;